<!--
  Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.

  https://www.mall4j.com/

  未经允许，不可做商业用途！

  版权所有，侵权必究！
-->

<template>
  <div class="Mall4j">
    <el-popover
      v-model:visible="visible"
      placement="bottom-start"
      width="325"
      trigger="click"
      popper-class="component-select-sku"
      @show="show"
    >
      <div class="popover-sku-box">
        <div
          v-for="(skuLine, key) in skuGroup"
          :key="key"
          class="sku-item"
        >
          <div class="sku-name">
            {{ key.replace('；', '') }}
          </div>
          <div class="sku-value">
            <div
              v-for="(skuLineItem, index) in skuLine"
              :key="index"
              class="item"
              :class="[
                selectedProp.find(
                  el => el.key === key.replace('；', '') && el.value === skuLineItem
                )
                  ? 'active'
                  : '',
                isSkuLineItemNotOptional(
                  allProperties,
                  selectedPropObj,
                  key,
                  skuLineItem,
                  propKeys
                )
                  ? 'not-optional'
                  : ''
              ]"
              @click="toChooseItem(skuLineItem, key, $event)"
            >
              {{ skuLineItem }}
            </div>
          </div>
        </div>
        <div class="footer">
          <div
            class="red btn"
            :class="{gary: !findSku}"
            @click="submit"
          >
            {{ $t("determine") }}
          </div>
          <div
            class="cancal btn"
            @click="close"
          >
            {{ $t("cancel") }}
          </div>
        </div>
      </div>
      <template #reference>
        <div
          class="prod-sku"
        >
          <span class="sku-name">{{ skuName }}</span>
          <img
            style="width: 8px;height: 4px;margin-left: 5px;margin-bottom: 2px;"
            src="@/assets/images/down.png"
            alt=""
          >
        </div>
      </template>
    </el-popover>
  </div>
</template>

<script setup>
import { ElMessage } from 'element-plus'
const emit = defineEmits(['getSku'])
const props = defineProps({
  skuName: {
    type: String,
    default: ''
  },
  skuList: {
    type: Array,
    default () {
      return []
    }
  },
  skuId: {
    type: Number,
    default: 0
  },
  prodId: {
    type: Number,
    default: 0
  },
  comboId: {
    type: Number,
    default: 0
  }
})

const visible = ref(false)
let defaultSku = ''

// 购物车中修改的sku列表
let cartChangeSkuList = []
const propKeys = ref([])
const selectedPropObj = ref({})
const skuGroup = ref([])
const allProperties = ref([])
const findSku = ref(false)

const close = () => {
  visible.value = !visible.value
}
const show = () => {
  if (!props.skuList.length) {
    getSkuListByProdId()
    return
  }
  groupSkuProp()
}
/**
 * 组装SKU
 */
const groupSkuProp = () => {
  const skuList = props.skuList.length ? props.skuList : cartChangeSkuList
  if (skuList.length === 1 && !skuList[0].properties) {
    defaultSku = skuList[0]
    return
  }
  const isSkuGroup = {}
  const isAllProperties = []
  const isPropKeys = []
  const isSelectedPropObj = {}
  let isDefaultSku = null
  for (let i = 0; i < skuList.length; i++) {
    let isDefault = false
    if (!isDefaultSku && skuList[i].skuId === props.skuId) {
      isDefaultSku = skuList[i]
      isDefault = true
    }
    const properties = skuList[i].properties // 版本:公开版;颜色:金色;内存:64GB
    isAllProperties.push(properties)
    const propList = properties.split(';') // ["版本:公开版","颜色:金色","内存:64GB"]

    for (let j = 0; j < propList.length; j++) {
      const index = propList[j].indexOf(':')
      const propval = [propList[j].slice(0, index), propList[j].substring(index + 1)] // ["版本","公开版"]
      let props = isSkuGroup[propval[0] + '；'] // 先取出 版本对应的值数组

      // 如果当前是默认选中的sku，把对应的属性值 组装到selectedProp
      if (isDefault) {
        isPropKeys.push(propval[0])
        isSelectedPropObj[propval[0]] = propval[1]
      }

      if (props === undefined) {
        props = [] // 假设还没有版本，新建个新的空数组
        props.push(propval[1]) // 把 "公开版" 放进空数组
      } else {
        if (props.indexOf(propval[1]) === -1) {
          // 如果数组里面没有"公开版"
          props.push(propval[1]) // 把 "公开版" 放进数组
        }
      }
      isSkuGroup[propval[0] + '；'] = props // 最后把数据 放回版本对应的值
    }
  }

  defaultSku = isDefaultSku
  propKeys.value = isPropKeys
  selectedPropObj.value = isSelectedPropObj
  parseSelectedObjToVals(skuList)
  skuGroup.value = isSkuGroup
  allProperties.value = isAllProperties
}

/**
 * 将已选的 {key:val,key2:val2}转换成 [val,val2]
 */
const selectedProp = ref([])

const parseSelectedObjToVals = () => {
  const skuList = cartChangeSkuList.length ? cartChangeSkuList : props.skuList
  const isSelectedPropObj = selectedPropObj.value
  let selectedProperties = ''
  const isSelectedProp = []
  for (const key in isSelectedPropObj) {
    isSelectedProp.push({ key, value: isSelectedPropObj[key] })
    selectedProperties += key + ':' + isSelectedPropObj[key] + ';'
  }
  selectedProperties = selectedProperties.substring(
    0,
    selectedProperties.length - 1
  )
  selectedProp.value = isSelectedProp
  selectedPropObj.value = isSelectedPropObj
  let isFindSku = false
  for (let i = 0; i < skuList.length; i++) {
    // 解决排序问题导致无法匹配
    if (
      compareArray(
        selectedProperties.split(';').sort(),
        skuList[i].properties.split(';').sort()
      )
    ) {
      isFindSku = true
      defaultSku = skuList[i]
      break
    }
  }
  findSku.value = isFindSku
}

/**
 * 比较两个数组中的元素是否相等
 * @param a1 第一个数组
 * @param a2 第二个数组
 * @return boolean 两个数组中的元素都相等则返回 true，反之返回 false
 */
const compareArray = (a1, a2) => {
  if (!a1 || !a2) {
    return false
  }
  if (a1.length !== a2.length) {
    return false
  }
  for (let i = 0, n = a1.length; i < n; i++) {
    if (a1[i] !== a2[i]) {
      return false
    }
  }
  return true
}
/**
 * 判断当前的规格值 是否可以选
 */
const isSkuLineItemNotOptional = (allProperties, selectedPropObjTemp, key, item, propKeys) => {
  const selectedPropObj = Object.assign({}, selectedPropObjTemp)
  let properties = ''
  selectedPropObj[key] = item
  for (let j = 0; j < propKeys.length; j++) {
    properties += propKeys[j] + ':' + selectedPropObj[propKeys[j]] + ';'
  }
  properties = properties.substring(0, properties.length - 1)
  for (let i = 0; i < allProperties.length; i++) {
    if (properties === allProperties[i]) {
      return false
    }
  }
  for (let i = 0; i < allProperties.length; i++) {
    if (allProperties[i].indexOf(item) >= 0) {
      return true
    }
  }
  return false
}

/**
 * 规格点击事件
 */
const toChooseItem = (skuLineItem, key) => {
  selectedPropObj.value[key.replace('；', '')] = skuLineItem
  parseSelectedObjToVals()
}
const submit = () => {
  if (!findSku.value) return
  if (!defaultSku.stocks) {
    ElMessage({
      message: $t('prodDetail.insufficientInventory'),
      type: 'warning',
      duration: 1000
    })
    return
  }
  close()
  emit('getSku', defaultSku)
}

/**
 * 根据商品id获取skuList
 */
const getSkuListByProdId = () => {
  http.get(props.comboId ? '/combo/skuList' : '/prod/skuList', {
    params: {
      comboId: props.comboId,
      prodId: props.prodId
    }
  }).then(({ data }) => {
    cartChangeSkuList = data
    groupSkuProp()
  })
}

</script>

<style lang="scss" scoped>
@use './index.scss';
</style>
